package com.xyz.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.xyz.aop.Param;
import com.xyz.entity.pojo.SystemFile;
import com.xyz.service.FileService;
import com.xyz.util.ResponseUtil;
import com.xyz.util.dto.DataResult;
import com.xyz.util.dto.LoginInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.util.*;

@RestController
@RequestMapping("system")
public class FileController {

    private static final Logger logger = LoggerFactory.getLogger(FileController.class);

    @Autowired
    private FileService fileService;

    public static String FILE_PATH;

    // 初始化FILE_PATH
    @PostConstruct
    public void init() {
        String path = this.getClass().getResource("/").getPath();
        if (path.indexOf("target") > 0) {
            FILE_PATH = path.replace("target/classes/", "file/");
        } else {
            FILE_PATH = path.replace("resources/", "file/");
        }
        File dist = new File(FILE_PATH);
        if (!dist.exists() && !dist.isDirectory()) {
            dist.mkdir();
        }
        logger.info("FILE_PATH初始化成功:" + FILE_PATH);
    }

    // 上传文件
    @PostMapping("uploadFile")
    public DataResult uploadFile(
            @RequestParam("files") MultipartFile[] files
    ) {
        if (files.length == 0) {
            return DataResult.build9200("未选择上传文件");
        }
        try {
            Map<String, String> map = new HashMap<>();
            for (MultipartFile file : files) {
                // 获取文件名
                String fileName = file.getOriginalFilename();
                // 获取文件的后缀名
                String suffixName = fileName == null ? null : fileName.substring(fileName.lastIndexOf("."));
                StringBuilder newPath = new StringBuilder();
                newPath.append(DateUtil.format(new Date(), "yyyy-MM-dd"));
                newPath.append("/");
                newPath.append(System.currentTimeMillis());
                newPath.append(RandomUtil.randomInt(10000000, 100000000));
                newPath.append(suffixName);
                File newFile = new File(FILE_PATH + newPath);
                // 检测是否存在目录
                if (!newFile.getParentFile().exists()) {
                    newFile.getParentFile().mkdirs();
                }
                // 文件上传
                file.transferTo(newFile);
                // 数据
                map.put(newPath.toString(), fileName);
            }
            // 保存路径到数据库
            List<String> fileCodeList = fileService.saveFile(map);
            return DataResult.build9100(fileCodeList);
        } catch (Exception e) {
            logger.error("uploadFile", e);
            return DataResult.build9500();
        }
    }

    // 读取文件
    @GetMapping("readFile/{hashCode}")
    public void readFile(
            HttpServletResponse response,
            @PathVariable String hashCode
    ) {
        // 文件读取策略：本地读取
        try {
            SystemFile sf = fileService.readFile(hashCode); // 获取File的文件码、路径，保证读取速度，先不获取二进制数据
            if (sf == null || StrUtil.isBlank(sf.getFileUrl())) { // 文件码错误或路径不存在
                return;
            }
            File file = new File(FILE_PATH + sf.getFileUrl()); // 获取文件绝对路径，创建File对象
            if (!file.exists()) { // 本地不存在目标文件
                return;
            }
            ResponseUtil.readFileResponse(response, file, sf.getFileName());
        } catch (Exception e) {
            logger.error("readFile/" + hashCode, e);
        }
    }

    // 删除文件
    @PostMapping("deleteFile")
    public DataResult deleteFile(
            LoginInfo li,
            @Param String fileCode
    ) {
        try {
            return fileService.deleteFile(li, fileCode);
        } catch (Exception e) {
            logger.error("deleteFile", e);
            return DataResult.build9500();
        }
    }

    // 将文件放在FILE_PATH下载
    // @GetMapping("download")
    // public void download(HttpServletResponse response) {
    //     try {
    //         ResponseUtil.download(FILE_PATH + "banner.gif", response);
    //     } catch (Exception ignored) {
    //     }
    // }

    // File转二进制
    private static byte[] FileToByte(File file) {
        byte[] by = new byte[(int) file.length()];
        try (InputStream is = Files.newInputStream(file.toPath()); ByteArrayOutputStream bs = new ByteArrayOutputStream()) {
            byte[] bb = new byte[2048];
            int ch = is.read(bb);
            while (ch != -1) {
                bs.write(bb, 0, ch);
                ch = is.read(bb);
            }
            by = bs.toByteArray();
        } catch (Exception ignored) {
        }
        return by;
    }

    // 二进制转File
    private static void ByteToFile(byte[] byteArray, String filePath) {
        File file = new File(filePath);
        try (FileOutputStream fos = new FileOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream(fos)) {
            bos.write(byteArray);
        } catch (Exception ignored) {
        }
    }

}
